CURSOR T-SQL-এ একটি প্রোগ্রামিং কনসেপ্ট যা আপনাকে একাধিক রেকর্ডের উপর কার্যক্রম চালানোর জন্য প্রতিটি রেকর্ড আলাদাভাবে প্রক্রিয়া করার সুযোগ প্রদান করে। সাধারণ SQL কোয়েরি একসাথে একাধিক রেকর্ড পরিচালনা করে, কিন্তু CURSOR প্রতিটি রেকর্ডকে একে একে (Row-By-Row) প্রক্রিয়া করতে ব্যবহৃত হয়। এটি তখন কার্যকরী হয় যখন SQL স্টেটমেন্ট দিয়ে একাধিক রেকর্ড পরিচালনা করা সম্ভব না, এবং আপনাকে প্রতিটি রেকর্ডের জন্য আলাদা কোনো কাজ করতে হয়।
CURSOR এর মৌলিক স্টেপস
- DECLARE CURSOR: একটি CURSOR ঘোষণা করা হয়, যা ডেটাবেসের রেকর্ডগুলো লোড করে।
- OPEN CURSOR: CURSORটি খুলে সেটি প্রক্রিয়া করার জন্য প্রস্তুত করা হয়।
- FETCH: CURSOR থেকে পরবর্তী রেকর্ডটি নেওয়া হয়।
- PROCESSING: FETCH করা রেকর্ডটি প্রক্রিয়া করা হয়।
- CLOSE CURSOR: CURSOR বন্ধ করা হয়।
- DEALLOCATE CURSOR: CURSOR মেমোরি থেকে মুক্ত করা হয়।
CURSOR সিনট্যাক্স
DECLARE cursor_name CURSOR FOR
SELECT column1, column2, ...
FROM table_name
WHERE condition;
OPEN cursor_name;
FETCH NEXT FROM cursor_name INTO @variable1, @variable2, ...;
WHILE @@FETCH_STATUS = 0
BEGIN
-- Process the data
-- Example: PRINT the data or perform calculations
FETCH NEXT FROM cursor_name INTO @variable1, @variable2, ...;
END
CLOSE cursor_name;
DEALLOCATE cursor_name;
- cursor_name: CURSOR এর নাম।
- SELECT: যে SELECT কুয়েরি দিয়ে CURSOR এর রেকর্ড তৈরি করা হবে।
- FETCH NEXT: পরবর্তী রেকর্ডটি নেওয়া হয় এবং সেটি ভ্যারিয়েবলে লোড করা হয়।
- @@FETCH_STATUS: এই সিস্টেম ফাংশন CURSOR এর বর্তমান অবস্থান চেক করে। যদি FETCH সফল হয়, তবে এটি 0 ফেরত দেয়।
উদাহরণ: CURSOR এর মাধ্যমে Row-By-Row প্রসেসিং
ধরা যাক, আপনার কাছে একটি Employees টেবিল আছে এবং আপনি প্রতিটি কর্মচারীর Salary কে ১০% বৃদ্ধি করতে চান। এটি করার জন্য, CURSOR ব্যবহার করা যেতে পারে:
DECLARE @EmployeeID INT, @Salary DECIMAL(10, 2);
DECLARE employee_cursor CURSOR FOR
SELECT EmployeeID, Salary
FROM Employees
WHERE Department = 'HR';
OPEN employee_cursor;
FETCH NEXT FROM employee_cursor INTO @EmployeeID, @Salary;
WHILE @@FETCH_STATUS = 0
BEGIN
-- Process each row
UPDATE Employees
SET Salary = @Salary * 1.10
WHERE EmployeeID = @EmployeeID;
-- Fetch the next row
FETCH NEXT FROM employee_cursor INTO @EmployeeID, @Salary;
END
CLOSE employee_cursor;
DEALLOCATE employee_cursor;
এখানে:
- DECLARE CURSOR:
employee_cursorনামে একটি CURSOR ঘোষণা করা হয়েছে, যাEmployeesটেবিলেরEmployeeIDএবংSalaryনিয়ে কাজ করবে। - OPEN: CURSOR খুলে দেওয়া হয়েছে এবং রেকর্ড নির্বাচন করা হয়েছে।
- FETCH NEXT: প্রথম রেকর্ডটি নেওয়া হয়েছে এবং এটি ভ্যারিয়েবলগুলিতে স্টোর করা হয়েছে।
- UPDATE: প্রতিটি রেকর্ডের জন্য Salary-কে ১০% বৃদ্ধি করা হয়েছে।
- WHILE:
@@FETCH_STATUS = 0নিশ্চিত করে যে CURSOR আরো রেকর্ড পাবার পর পরবর্তী রেকর্ডটিFETCH NEXTএর মাধ্যমে প্রসেস করা হবে। - CLOSE & DEALLOCATE: শেষে CURSOR বন্ধ এবং মেমরি থেকে মুক্ত করা হয়েছে।
CURSOR এর সুবিধা
- Row-By-Row প্রক্রিয়াকরণ: যখন আপনাকে একাধিক রেকর্ডের উপর শর্তবিশেষে আলাদাভাবে কাজ করতে হয়, তখন CURSOR খুবই কার্যকর।
- কমপ্লেক্স লজিক প্রয়োগ: কিছু নির্দিষ্ট লজিকের জন্য যখন আপনাকে প্রতিটি রেকর্ডে আলাদা কাজ করতে হয়, CURSOR ব্যবহার করা যেতে পারে।
- ডেটাবেস আপডেট করা: CURSOR এর মাধ্যমে আপনি প্রতিটি রেকর্ডে প্রক্রিয়া বা গণনা করতে পারেন এবং তারপর ডেটাবেসে সেই পরিবর্তনগুলো আপডেট করতে পারেন।
CURSOR এর অসুবিধা
- পারফরম্যান্সের সমস্যা: CURSOR প্রক্রিয়া সাধারণ SQL স্টেটমেন্টের তুলনায় ধীর গতিতে চলে। কারণ এটি একে একে রেকর্ড প্রক্রিয়া করে, তাই বড় ডেটাসেটের জন্য এটি বেশ সময়সাপেক্ষ হতে পারে।
- ডেটাবেস লকিং: CURSOR ব্যবহার করলে প্রতিটি রেকর্ডে লকিং হতে পারে, যা অন্যান্য ট্রানজ্যাকশনকে প্রভাবিত করতে পারে।
- পরিষ্কারকরণ: CURSOR ব্যবহারের পরে অবশ্যই CLOSE এবং DEALLOCATE করতে হয়, অন্যথায় মেমরি লিক হতে পারে।
CURSOR Alternatives (বিকল্প)
SET Based Operations: যদি সম্ভব হয়, SET-based SQL operations (যেমন
UPDATE,SELECT,INSERT) ব্যবহার করা ভালো, কারণ এগুলি অনেক দ্রুত এবং পারফরম্যান্সের জন্য বেশি উপকারী।উদাহরণ:
UPDATE Employees SET Salary = Salary * 1.10 WHERE Department = 'HR';- CTE (Common Table Expression): CTE ব্যবহার করে কিছু কার্যক্রম আরও কার্যকরভাবে করা যেতে পারে, বিশেষত যখন ট্রানজ্যাকশনাল ডেটা ম্যানিপুলেশন করতে হয়।
সারাংশ
CURSOR T-SQL-এ একটি অত্যন্ত শক্তিশালী টুল যা Row-By-Row প্রসেসিং করার জন্য ব্যবহৃত হয়। এটি একটি সময়সাপেক্ষ অপারেশন, তবে কখনো কখনো এটি ব্যবহার করা প্রয়োজন হতে পারে যখন আপনাকে প্রতিটি রেকর্ডের উপর আলাদাভাবে কাজ করতে হয়। তবে, সাধারণত SET-based operations ব্যবহার করা উচিত, কারণ তা অনেক দ্রুত এবং বেশি পারফরম্যান্স-ভিত্তিক হয়।